using System;
using System.Collections.Generic;

using Atomic.Libraries.Mathematics;

namespace Atomic.Libraries
{
	[Serializable]
	public class LinkedMatrix<TKey, TValue>
	{
		private int n;
		private TValue[,] entries;
		private Dictionary<TKey, int> indices;

		public LinkedMatrix(IEnumerable<TKey> parent, TValue[,] entries)
			: this(new List<TKey>(parent), entries)
		{
		}

		private LinkedMatrix(IList<TKey> parent, TValue[,] entries)
		{
			n = parent.Count;

			if (entries.GetLength(0) != n || entries.GetLength(1) != n)
			{
				throw new ArgumentException("Matrix size doesn't match size of parent list.");
			}

			this.entries = (TValue[,])entries.Clone();

			indices = new Dictionary<TKey, int>();
			for (int i = 0; i < n; i++)
			{
				TKey key = parent[i];
				indices.Add(key, i);
			}
		}
	
		public TValue this[TKey key1, TKey key2]
		{
			get
			{
				return this[indices[key1], indices[key2]];
			}
		}

		public TValue this[int row, int column]
		{
			get
			{
				return entries[row, column];
			}
		}

		public int Count
		{
			get
			{
				return n;
			}
		}
	}

	[Serializable]
	public class LinkedMatrix<T> : LinkedMatrix<T, double>
	{
		public LinkedMatrix(IEnumerable<T> parent, double[,] entries)
			: base(parent, entries)
		{
		}

		public LinkedMatrix(IEnumerable<T> parent, Matrix entries)
			: this(parent, entries.ToArray())
		{
		}

		public Matrix ToMatrix()
		{
			throw new NotImplementedException();
		}
	}
}
